package org.raycloud.service;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.raycloud.Excption.CheckCodeExcption;
import org.raycloud.Excption.LimitedException;
import org.raycloud.Excption.NoUserFoundExcption;
import org.raycloud.Excption.XHRTimeoutException;
import org.raycloud.commons.id2context;
import org.raycloud.service.impl.CustomerGetInfos;
import org.raycloud.service.impl.NormalSalesGetInfos;
import org.raycloud.service.impl.TMALLSalesGetInfos;
import org.raycloud.vo.shop_rate_list;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeoutException;


/**
 * Created by Administrator on 2014/4/1.
 * Time: 11:15
 */
public class TaoBaoSpider {


    Long id = null;
    File dest = new File("c://test.txt");
    shop_rate_list list;
    CookieStore cookieStore =new BasicCookieStore();
    CloseableHttpClient httpclient = HttpClients.createDefault();;
    String cookies="\tcookie2=3ec3c8c012714dbf88c07da5bff57b31; t=ee7012013400c9a0944333d0c0752b14; uc1=cookie14=UoLVYyrdtvjumQ%3D%3D; v=0; pnm_cku822=046fCJmZk4PGRVHHxtOZXsnZHo9ay11PWsQKg%3D%3D%7CfyJ6Zyd9OWggZ3EgZ3Upaxo%3D%7CfiB4D157YHtufDUqfHY4fmo7dCQaAxlbU1AFS2IT%7CeSRiYjNhIHA2emQwdGQ7e2cheDp9PHtoO3hpN3FrLXk4ZCZmdSVzCA%3D%3D%7CeCVoaEASTBRXEQVOCQNNFQhSEzwI%7CeyNneyR3KXIua3kvd2I7eAk%3D; mt=ci%3D0_0; cna=c6XJC5FRXT4CAbeBn6bVQE/J; _tb_token_=e3e6ed77e1d68";
    /**
     * 初始化  ID  构造
     *
     * @param id
     */
    public TaoBaoSpider(Long id) {
        this.id = id;
        list = new shop_rate_list(id);
    }

    //开始
    public void start() throws NoUserFoundExcption, IOException, CheckCodeExcption, TimeoutException, XHRTimeoutException, LimitedException {
        System.out.println("============================================");


        //获取基础用户页面信息
        Long l1 = System.currentTimeMillis();
        Document doc = this.getDombyUrl("http://rate.taobao.com/user-rate-" + id.toString() + ".htm", null, null);
//        System.out.println(doc.toString());
        Long l2 = System.currentTimeMillis() - l1;
        System.out.println("获取用户页面时间：" + l2 + "ms");

//        System.out.println(doc);
        //判断是否访问频繁
        if (this.isLimited(doc)) {
            throw new LimitedException();
        }

        //解析页面数据
        Long l3 = System.currentTimeMillis();
        if (this.isUserFound(doc)) {
            //    判断是否存在用户
            String type = this.isTypeUser(doc);
            if (type.equals("普买")) {
                this.type1parser(doc);
            } else if (type.equals("普卖")) {
                this.type2parser(doc);
            } else if (type.equals("天卖")) {
                this.type3parser(doc);
            }
        }


    }

    //是否访问受限
    public boolean isLimited(Document doc) {

        Elements ele = doc.select("title");
        if (ele.text().toString().equals("亲，访问受限了")) {
            return true;
        }
        return false;

    }

    /**
     * 普通买家 信息存储
     * 1、基础信息存储
     * 2、半年内 给他人评价 存储
     * 3、半年外 给他人评价 存储
     * doc
     *
     * @param doc
     * @throws IOException
     * @throws CheckCodeExcption
     */
    public void type1parser(Document doc) throws IOException, CheckCodeExcption, XHRTimeoutException {

        //  如果是普通买家执行操作
        IGetUserInfos parser = new CustomerGetInfos(this.list);

        // 存储用户基础页面信息
        parser.parserUserInfo(doc);

        //解析XHR数据
        String url;
        Long l5 = System.currentTimeMillis();
        while (true) {
            url = "http://rate.taobao.com/member_rate.htm" + this.XHRparam(list.getCurrentPageNum() + 1, "1", "3", "", "1");
            String s1 = this.getStrByUrl(url, cookieStore,"Uapplication/js");
//            System.out.println(s1);
            if (!parser.parserXHRinfo3(s1)) break;
            else {
                System.out.println("获取成功！\n当前页" + list.getCurrentPageNum() + "\n最大页：" + list.getMaxPage() + "\n内容" + list.getList().size());
                System.out.println("访问地址：" + url);
                System.out.println("============================================");
            }
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            break;
        }
        Long l6 = System.currentTimeMillis() - l5;
        System.out.println("XHR数据解析：" + l6 + "ms");
        System.out.println("解析完毕共:" + list.getList().size() + "数据");

//
//        // 存储 历史 给他人的评价 页面 数据信息
//        int page = 0;
//        while (true) {
//            page++;
//            Long l7 = System.currentTimeMillis();
//            doc = this.getDombyUrl("http://ratehis.taobao.com/user-rate-" + id2context.getString(this.id) + this.historyParam(page), null, null);
//            Long l8 = System.currentTimeMillis() - l7;
//            System.out.println("获取历史页面第" + page + "页的时间：" + l8 + "ms" + "\n页面地址：" + "http://ratehis.taobao.com/user-rate-" + id2context.getString(this.id) + this.historyParam(page));
//            if (!parser.parserRateHistoryInfo3(doc)) break;
//        }


    }

    // 普通卖家
    public void type2parser(Document doc) throws IOException, CheckCodeExcption, XHRTimeoutException {
        //  如果是普通买家执行操作
        IGetUserInfos parser = new NormalSalesGetInfos(this.list);

        // 存储用户基础页面信息
        parser.parserUserInfo(doc);


        //解析XHR数据
        String url = "";
        Long l5 = System.currentTimeMillis();
        while (true) {
            url = "http://rate.taobao.com/member_rate.htm" + this.XHRparam(list.getCurrentPageNum() + 1, "1", "3", "", "1");
            String s1 = this.getStrByUrl(url, cookieStore,"Uapplication/js");
            if (!parser.parserXHRinfo3(s1)) break;
            else {
                System.out.println("获取成功！\n当前页" + list.getCurrentPageNum() + "\n最大页：" + list.getMaxPage() + "\n内容" + list.getList().size());
                System.out.println("访问地址：" + url);
                System.out.println("============================================");
            }
            try {
                Thread.sleep(60000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            break;
        }
        Long l6 = System.currentTimeMillis() - l5;
        System.out.println("XHR数据解析：" + l6 + "ms");
        System.out.println("解析完毕共:" + list.getList().size() + "数据");

//
//        // 存储 历史 给他人的评价 页面 数据信息
//        int page = 0;
//        while (true) {
//            page++;
//            Long l7 = System.currentTimeMillis();
//            doc = this.getDombyUrl("http://ratehis.taobao.com/user-rate-" + id2context.getString(this.id) + this.historyParam(page), null, null);
//            Long l8 = System.currentTimeMillis() - l7;
//            System.out.println("获取历史页面第" + page + "页的时间：" + l8 + "ms" + "\n页面地址：" + "http://ratehis.taobao.com/user-rate-" + id2context.getString(this.id) + this.historyParam(page));
//            if (!parser.parserRateHistoryInfo3(doc)) break;
//        }
    }

    // 天猫卖家
    public void type3parser(Document doc) throws XHRTimeoutException, CheckCodeExcption {

        //  如果是普通买家执行操作
        IGetUserInfos parser = new TMALLSalesGetInfos(this.list);
//
        // 存储用户基础页面信息
        parser.parserUserInfo(doc);


        //解析XHR数据
        String url = "";
        Long l5 = System.currentTimeMillis();
        while (true) {
            String s1 = null;
            try {
                url = "http://rate.taobao.com/member_rate.htm" + this.XHRparam(list.getCurrentPageNum() + 1, "0", "0", "1", "2");
                s1 = this.getStrByUrl(url, cookieStore,"Uapplication/js");
            } catch (IOException e) {
                System.out.println("get请求超时：" + s1);
            }
            if (!parser.parserXHRinfo0(s1)) break;
            else {
                System.out.println("获取成功！\n当前页" + list.getCurrentPageNum() + "\n最大页：" + list.getMaxPage() + "\n内容" + list.getList().size());
                System.out.println("访问地址：" + url);
                System.out.println("============================================");
            }

            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            break;
        }
        Long l6 = System.currentTimeMillis() - l5;
        System.out.println("XHR数据解析：" + l6 + "ms");
        System.out.println("解析完毕共:" + list.getList().size() + "数据");

    }

    /**
     * 封装 ajax get请求的 参数头
     *
     * @param page
     * @return 返回一个 get参数 字符串
     * <p/>
     * 配置方案
     * page direction  rater
     * X     0           0      来自买家的评价
     * X     0           1      来自卖家的评价
     * X     1           3      给别人的评价
     */
    public String XHRparam(Integer page, String direction, String rater, String content, String identity) {
        StringBuilder sb = new StringBuilder("?");
        String time = System.currentTimeMillis() + "_111";
        String idx = id2context.getString(this.id);
        sb.append("_ksTS" + "=" + time + "&");
        sb.append("callback" + "=" + "shop_rate_list" + "&");
        //买家页面里面  1 有评论内容； 空 uncheck
        sb.append("content" + "=" + content + "&");
        //0 tab1  1 tab2
        sb.append("direction" + "=" + direction + "&");
        //默认不变
        sb.append("from" + "=" + "rate" + "&");
        //1普通用户  2 天猫用户
        sb.append("identity" + "=" + identity + "&");
        //页数
//        sb.append("page" + "=" + page.toString() + "&");
        //  0 来自买家的评价    1 来自卖家评价 ； 3给别人的评价
        sb.append("rater" + "=" + rater + "&");
        //这个参数  空 全部；1 好评；0 中评；-1 差评 2  有追加评论
        sb.append("result" + "=" + "" + "&");
        //ID 与加密互转
        sb.append("user_id" + "=" + idx + "&");
        //是否有追评
        sb.append("append" + "=" + "");
        // timeline  几年前数据

        return sb.toString();
    }

    /**
     * 历史评价页 get请求url拼装
     *
     * @return get的 url尾部
     */
    public String historyParam(int currentPage) {

//        isarchive|true--				不知道
//        isarchive
//                goodNeutralOrBad
//        timeLine
//                detailed
//        ismore
//                showContent
//        maxPage
//        maxPage|2

        StringBuilder sb = new StringBuilder("--");
        //不知道
        sb.append("isarchive" + "|" + "true" + "--");
        sb.append("ismore" + "|" + "" + "--");
        sb.append("timeLine" + "|" + "" + "--");
        //     			数据身份  0 来自买家 1来自卖家  3给他人的评价
        sb.append("buyerOrSeller" + "|" + "3" + "--");
        // 空 评价 1好评 0中评 -1 差评
        sb.append("goodNeutralOrBad" + "|" + "" + "--");
        sb.append("detailed" + "|" + "--");
        // 	0 来自买家卖家   1给他人评价
        sb.append("receivedOrPosted" + "|" + "1" + "--");
        //显示评价
        sb.append("showContent" + "|" + "" + "--");
        //        currentPage|3					当前页
        sb.append("currentPage" + "|" + currentPage + "--");
        //
        //sb.append("maxPage" + "|" + "2");
        sb.append(".htm#RateType");


        return sb.toString();
    }

    /**
     * 通过httpclient 提交get方法 请求
     *
     * @param url         地址
     * @param cookieStore httpclient 的 cookice对象,提交时使用cookice
     * @return html 或者 json字符串
     * @throws IOException
     */
    public String getStrByUrl(String url, CookieStore cookieStore, String contentMimeType) throws IOException {
        StringBuilder entityStringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        String s1 = null;
        HttpGet httpget = new HttpGet(url);
        // 创建cookie store的本地实例
        if (cookieStore == null) cookieStore = new BasicCookieStore();
        // 创建本地的HTTP内容
//        HttpContext localContext = new BasicHttpContext();
//        // 绑定定制的cookie store到本地内容中
//        localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
        //超时配置
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();
        httpget.setConfig(requestConfig);
        // 作为参数传递本地内容
        CloseableHttpResponse response = httpclient.execute(httpget);

        response.addHeader("Accept","*/*");
        response.addHeader("Accept-Encoding","gzip, deflate");
        response.addHeader("zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3","");
        response.addHeader("Connection","keep-alive");
        response.addHeader("Host","rate.taobao.com");
        response.addHeader("Cookie",cookies);
        response.addHeader("Referer","http://rate.taobao.com/user-rate-1763577710.htm");
        response.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0");

        Header[] list=response.getAllHeaders();
        for (Header header : list) {
            System.out.println(header.toString());
        }

//        List<Cookie> list = cookieStore.getCookies();
//
//        for (Cookie cookie : list) {
//            System.out.println(cookie.toString());
//        }
//        String contentMimeType = ContentType.getOrDefault(response.getEntity()).getMimeType();
        System.out.println("解析地址：" + url);
        System.out.println("解析类型："+contentMimeType);
        if (contentMimeType.equals("Uapplication/js")) {
            try {
                HttpEntity httpEntity = response.getEntity();
                if (httpEntity != null) {
                    try {
                        bufferedReader = new BufferedReader
                                (new InputStreamReader(httpEntity.getContent(), "GBK"), 8 * 1024);
                        String line = null;
                        while ((line = bufferedReader.readLine()) != null) {
                            entityStringBuilder.append(line + "/n");

                        }
                        // FileUtils.writeStringToFile(dest, entityStringBuilder.toString(), "GBK");
                        s1 = entityStringBuilder.subSequence(entityStringBuilder.toString().indexOf("{"), entityStringBuilder.toString().lastIndexOf("}") + 1).toString();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } finally {
                response.close();
            }
            return s1;
        } else if (contentMimeType.equals("text/html")) {
            String Result = EntityUtils.toString(response.getEntity());
            return Result;
        }
        return "";
    }


    /**
     * 通过httpclient发送get http请求，返回jsoup DOM树
     *
     * @param url       地址
     * @param cookiemap cookice
     * @param datamap   请求参数
     * @return
     */
    public Document getDombyUrl(String url, Map<String, String> cookiemap, Map<String, String> datamap) throws TimeoutException, IOException {
        Document doc = null;
        String html = null;
        System.out.println("用户页面信息地址：" + url);
        html = getStrByUrl(url, cookieStore,"text/html");
        doc = Jsoup.parse(html);
        return doc;

    }

    /**
     * 通过 htmlunit2.1 浏览器访问返回 str页面数据
     *
     * @param url
     * @return
     */
    public String getStrbyBrowser(String url) {
        final WebClient webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_8);
        webClient.setCssEnabled(false);
        webClient.setJavaScriptEnabled(false);
        webClient.setTimeout(5000);
        HtmlPage page = null;
        try {
            page = webClient.getPage(url);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return page.asXml();
    }

    /**
     * 通过 htmlunit2.1 浏览器访问返回 jsoup Dom树页面数据
     *
     * @param url
     * @return jsoup document
     */
    public Document getDombyBrowser(String url) {
        Document doc = null;
        doc = Jsoup.parse(this.getStrbyBrowser(url));
        return doc;
    }

    /**
     * 判断是否存在用户
     *
     * @param doc 文档树
     * @return 用户找到ture
     * @throws NoUserFoundExcption
     */
    public Boolean isUserFound(Document doc) throws NoUserFoundExcption {
        Boolean flag = true;
        Elements eleError = doc.select("div.msg24>p.attention:contains(该用户)");
        //判断账号是否存在
        if (!eleError.isEmpty()) {
            flag = false;
            throw new NoUserFoundExcption("Error:" + eleError.text() + "||UID:" + this.id);
        }
        return flag;
    }

    /**
     * 如果存在用户，用户页面类型
     *
     * @param doc
     */
    public String isTypeUser(Document doc) {
        Elements ele1 = doc.select("span.mlogo>a");
        Elements ele2 = doc.select("div.bd>div.info-block>ul.sep>li:contains(卖家信用)");
        Elements ele3 = doc.select("div.bd>div.info-block>ul.sep>li:contains(买家信用)");
        //System.out.println(ele1.text());
        if (ele1.text().equals("天猫Tmall.com")) {
            System.out.println("页面类型：天猫卖家");
            return "天卖";

        } else if (ele2.isEmpty()) {
            System.out.println("页面类型：普通买家");
            return "普买";
        } else if (!ele2.isEmpty() && !ele3.isEmpty()) {
            System.out.println("页面类型：普通卖家");
            return "普卖";
        }
        return "未知类型";
    }

    public void test(){
    int count=0;
        while (true) {
            this.id++;
//            if (this.id%10==0){
//
////                this.cookieStore.clear();
//               cookies= Htmlunitdemo.getCookies();
//
//            }

            String url = "http://rate.taobao.com/member_rate.htm" + this.XHRparam(list.getCurrentPageNum() + 1, "1", "3", "", "1");
            try {
                String s1 = this.getStrByUrl(url, cookieStore, "Uapplication/js");
                System.out.println(s1);
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                count++;
                System.out.println("这是第"+count+"个");
                Thread.sleep(2500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
    public static void main(String[] args) {


        //用户不存在页面
//        TaoBaoSpider sp = new TaoBaoSpider(17635770L);

        //普通卖家ID
        TaoBaoSpider sp = new TaoBaoSpider(1763577710L);
//        TaoBaoSpider sp = new TaoBaoSpider(381696371L);

        //天猫卖家ID
//        TaoBaoSpider sp = new TaoBaoSpider(528296282L);


        //普通买家ID
//        TaoBaoSpider sp = new TaoBaoSpider(10086L);







//        try {
//            String ss = sp.getStrByUrl("http://sdw.hunnu.edu.cn/", "html");
//            System.out.println(ss);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        System.exit(0);
//
        try {
            sp.start();
        } catch (NoUserFoundExcption noUserFoundExcption) {
            noUserFoundExcption.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (CheckCodeExcption checkCodeExcption) {
            checkCodeExcption.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        } catch (XHRTimeoutException e) {
            e.printStackTrace();
        } catch (LimitedException e) {
            e.printStackTrace();
        }


    }
}
